package com.woyowodaows.utils;

import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.CountDownTimer;
import android.provider.ContactsContract;
import android.support.design.widget.TextInputLayout;
import android.text.Editable;
import android.text.Selection;
import android.text.Spannable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.text.method.HideReturnsTransformationMethod;
import android.text.method.PasswordTransformationMethod;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.TextView;


import com.woyowodaows.application.MyApplication;

import java.util.regex.Matcher;
import java.util.regex.Pattern;


/**
 * 正则表达式工具类
 *
 * @author haiwei
 *         2017/2/26
 */
public class RegularUtils {

    private static Context context = MyApplication.getApplicationContext();
    private static RegularUtils regularUtil;
    private CountDownTimer downTimer;
    public int second = 60000;


    public static RegularUtils getInstate() {
        if (regularUtil == null) {
            synchronized (RegularUtils.class) {
                if (regularUtil == null) {
                    regularUtil = new RegularUtils();
                }
            }
        }
        return regularUtil;
    }

    /**
     *允许汉字和字母
     *
     */
    public static boolean isHZ(String str){
        String regex="^[A-Za-z\\u4e00-\\u9fa5]+$";
        Pattern p = Pattern.compile(regex);
        Matcher m = p.matcher(str);
        return m.matches();

    }

    /**
     * 匹配汉字
     * @param str
     * @return
     */
    public static boolean isChinese(String str){
        String regex =  "[\\u4e00-\\u9fa5]+$";
        Pattern p = Pattern.compile(regex);
        Matcher m = p.matcher(str);
        return m.matches();

    }

    /**
     * 验证手机号码 isCorrect如果为true则验证成功 false则失败
     *
     * @param phoneNumber
     */
    public boolean rehularPhone(String phoneNumber) {
        Pattern p = Pattern.compile("^((17[0-9])|(13[0-9])|(14[0-9])|(15[0-9])|(18[0-9])|(19[0-9])|(16[0-9]))\\d{8}$");
        Matcher m = p.matcher(phoneNumber);
        return m.matches();
    }
    public static boolean isMobileNO(String mobileNums) {
        /**
         * 判断字符串是否符合手机号码格式
         * 移动号段: 134,135,136,137,138,139,147,150,151,152,157,158,159,170,178,182,183,184,187,188
         * 联通号段: 130,131,132,145,155,156,170,171,175,176,185,186
         * 电信号段: 133,149,153,170,173,177,180,181,189
         * @param str
         * @return 待检测的字符串
         */
        String telRegex = "^((13[0-9])|(14[5,7,9])|(15[^4])|(18[0-9])|(17[0,1,3,5,6,7,8]))\\d{8}$";// "[1]"代表下一位为数字可以是几，"[0-9]"代表可以为0-9中的一个，"[5,7,9]"表示可以是5,7,9中的任意一位,[^4]表示除4以外的任何一个,\\d{9}"代表后面是可以是0～9的数字，有9位。
        if (TextUtils.isEmpty(mobileNums))
            return false;
        else
            return mobileNums.matches(telRegex);
    }

    /**
     * 手机号码中间4位****显示
     */

    public static String getPhone(String s){
        return s.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");
    }


    /**
     * 数据为空提示
     */
    public boolean checkEmpty(CharSequence name, TextInputLayout layout, String empty) {
        if (TextUtils.isEmpty(name)) {
            layout.setErrorEnabled(true);
            layout.setError(empty);
            layout.getEditText().setFocusable(true);
            layout.getEditText().requestFocus();
            return true;
        } else {
            layout.setError(null);
            layout.setErrorEnabled(false);
        }
        return false;
    }

    /**
     * 输入框错误信息制空
     */
    public void checkSetEmpty(CharSequence name, TextInputLayout layout) {
        if (!TextUtils.isEmpty(name)) {
            layout.setError(null);
            layout.setErrorEnabled(false);
        }
    }

    /**
     * 数据为空提示
     */
    public void checkEmpty(TextInputLayout layout, String empty) {
        if (!TextUtils.isEmpty(empty)) {
            layout.setErrorEnabled(true);
            layout.setError(empty);
            layout.getEditText().setFocusable(true);
            layout.getEditText().requestFocus();
        }
    }

    /**
     * 判定输入汉字
     */

    public static boolean isChinese(char c) {

        Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);

        if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A || ub == Character.UnicodeBlock.GENERAL_PUNCTUATION || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS) {

            return true;

        }

        return false;

    }


    /**
     * 检测String是否全是中文
     */

    public static boolean checkNameChese(String name) {

        boolean res = true;

        char[] cTemp = name.toCharArray();

        for (int i = 0; i < name.length(); i++) {

            if (!isChinese(cTemp[i])) {

                res = false;

                break;

            }

        }

        return res;

    }


    /**
     * 验证身份证号是否符合规则
     */
    public boolean personIdValidation(String text) {
        String regx = "[0-9]{17}x";
        String reg2 = "[0-9]{17}X";
        String reg1 = "[0-9]{15}";
        String regex = "[0-9]{18}";
        return text.matches(regx) || text.matches(reg1) || text.matches(regex) || text.matches(reg2);
    }


    /**
     * 验证是否是真实url
     */
    public boolean isUrl(String urlString) {
        String regex = "^(https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]";
        Pattern patt = Pattern.compile(regex);
        Matcher matcher = patt.matcher(urlString);
        boolean isMatch = matcher.matches();
        return isMatch;
    }

    /**
     * 判断email格式是否正确
     */
    public boolean isEmail(String email) {
        String str = "^([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$";
        Pattern p = Pattern.compile(str);
        Matcher m = p.matcher(email);
        return m.matches();
    }


    /**
     * 判断是否只包含英文
     */
    public static boolean isEnglish(String english) {
        String str = ".*[a-zA-Z]";
        Pattern pattern = Pattern.compile(str);
        Matcher matcher = pattern.matcher(english);
        return matcher.matches();
    }


    /**
     * 判断同时有字母和数字字符
     *
     * @param text
     * @return
     */
    public boolean includeEnglishNumber(String text) {
        String str = ".*[a-zA-Z].*[0-9]|.*[0-9].*[a-zA-Z]";
        Pattern pattern = Pattern.compile(str);
        Matcher matcher = pattern.matcher(text);
        return matcher.matches();
    }

    /**
     * 倒计时
     *
     * @param tv_register_get_code
     */
    public void getVerificationCode(final TextView tv_register_get_code) {
        downTimer = new CountDownTimer(second + 500, 1000) {
            @Override
            public void onTick(long time) {
                tv_register_get_code.setText("已发送(" + String.valueOf(time / 1000) + "s)");
                tv_register_get_code.setEnabled(false);
            }

            @Override
            public void onFinish() {
                tv_register_get_code.setText("获取验证码");
                tv_register_get_code.setEnabled(true);
            }
        };
        downTimer.start();
    }

    //移除验证码计时
    public void removeVerificationCode() {
        if (downTimer != null) {
            downTimer.cancel();
        }
    }

    /**
     * 切换文本和密码状态
     */
    public void setPasswordState(boolean isShowPassword, CheckBox checkBox, EditText editText) {
        if (isShowPassword) {
            //设置文本为可见
            editText.setTransformationMethod(HideReturnsTransformationMethod.getInstance());
        } else {
            //设置文本为密码
            editText.setTransformationMethod(PasswordTransformationMethod.getInstance());
        }
        editText.postInvalidate();
        //切换后将EditText光标置于末尾
        CharSequence charSequence = editText.getText();
        if (charSequence instanceof Spannable) {
            Spannable spannableText = (Spannable) charSequence;
            Selection.extendSelection(spannableText, charSequence.length());
        }
    }

    /**
     * 获取手机联系人
     */
    public String[] getPhoneContacts(Uri uri) {
        String[] contact = new String[2];
        //得到ContentResolver对象
        ContentResolver cr = context.getContentResolver();
        //取得电话本中开始一项的光标
        Cursor cursor = cr.query(uri, null, null, null, null);
        if (cursor != null) {
            cursor.moveToFirst();
            //取得联系人姓名
            int nameFieldColumnIndex = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
            contact[0] = cursor.getString(nameFieldColumnIndex);
            //取得电话号码
            String id = cursor.getString(cursor.getColumnIndex(ContactsContract.RawContacts._ID));// "_id"
            Cursor phoneCursor = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI//
                    , new String[]{ContactsContract.CommonDataKinds.Phone.NUMBER}// "data1"
                    , "raw_contact_id=?", new String[]{id}, null);
            if (phoneCursor.moveToNext()) {
                contact[1] = phoneCursor.getString(phoneCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
            }
            phoneCursor.close();
            cursor.close();
        } else {
            return null;
        }
//获取所有联系人
//        String[] projection = new String[]{ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.NUMBER};
//        Cursor cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, projection, null, null, null);
//        if(cursor != null){
//            while (cursor.moveToNext()) {
//                String name = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
//                String phoneNum = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
//                if(!TextUtils.isEmpty(phoneNum)){
//                    contactsList.add(new PhoneContact(name, phoneNum.trim().replace(" ", "").replace("-","")));
//                }
//            }
//            cursor.close();
//        }

        return contact;
    }


    /**
     * 自动补齐小数点
     *
     * @param editText
     */
    public static void setPricePoint(final EditText editText) {
        editText.addTextChangedListener(new TextWatcher() {

            @Override
            public void onTextChanged(CharSequence s, int start, int before,
                                      int count) {
                if (s.toString().contains(".")) {
                    if (s.length() - 1 - s.toString().indexOf(".") > 2) {
                        s = s.toString().subSequence(0,
                                s.toString().indexOf(".") + 3);
                        editText.setText(s);
                        editText.setSelection(s.length());
                    }
                }
                if (s.toString().trim().substring(0).equals(".")) {
                    s = "0" + s;
                    editText.setText(s);
                    editText.setSelection(2);
                }

                if (s.toString().startsWith("0")
                        && s.toString().trim().length() > 1) {
                    if (!s.toString().substring(1, 2).equals(".")) {
                        editText.setText(s.subSequence(1, s.length()));
                        editText.setSelection(1);
                    }
                }

                if (addTextChangedListener != null){
                    addTextChangedListener.onTextChanged(editText.getText().toString());
                }
            }

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count,
                                          int after) {
            }

            @Override
            public void afterTextChanged(Editable s) {
            }
        });
    }


    public interface addTextChangedListener{
        void onTextChanged(String text);
    }


    private static addTextChangedListener addTextChangedListener;

    public void setAddTextChangedListener(RegularUtils.addTextChangedListener addTextChangedListener) {
        this.addTextChangedListener = addTextChangedListener;
    }

    //判断整数（int）
    public boolean isInteger(String str) {
        if (null == str || "".equals(str)) {
            return false;
        }
        Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$");
        return pattern.matcher(str).matches();
    }

    //判断浮点数（double和float）
    public boolean isDouble(String str) {
        if (null == str || "".equals(str)) {
            return false;
        }
        Pattern pattern = Pattern.compile("^[-\\+]?[.\\d]*$");
        return pattern.matcher(str).matches();
    }


    // Description: 银行卡号Luhm校验
    // Luhm校验规则：16位银行卡号（19位通用）:
    // 1.将未带校验位的 15（或18）位卡号从右依次编号 1 到 15（18），位于奇数位号上的数字乘以 2。
    // 2.将奇位乘积的个十位全部相加，再加上所有偶数位上的数字。
    // 3.将加法和加上校验位能被 10 整除。
    // 开头6位
    // private final static String strBin =
    // "10,18,30,35,37,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,58,60,62,65,68,69,84,87,88,94,95,98,99";
    private final static String SUCCESS = "true";


    private final static String BAD_LENGTH = "银行卡号长度必须在16到19之间";


    private final static String NOT_NUMBER = "银行卡必须全部为数字";


    private final static String ILLEGAL_NUMBER = "银行卡不符合规则";


    /**
     * 验证是否是银行卡
     *
     * @param bankno
     * @return
     */
    public String isBankCradNumber(String bankno) {
        if (bankno.length() < 16 || bankno.length() > 19) {
            return BAD_LENGTH;
        }


        Pattern pattern = Pattern.compile("[0-9]*");
        Matcher match = pattern.matcher(bankno);
        if (match.matches() == false) {
            return NOT_NUMBER;
        }


        int lastNum = Integer.parseInt(bankno.substring(bankno.length() - 1,
                bankno.length()));// 取出最后一位（与luhm进行比较）


        String first15Num = bankno.substring(0, bankno.length() - 1);// 前15或18位
        char[] newArr = new char[first15Num.length()]; // 倒叙装入newArr
        char[] tempArr = first15Num.toCharArray();
        for (int i = 0; i < tempArr.length; i++) {
            newArr[tempArr.length - 1 - i] = tempArr[i];
        }


        int[] arrSingleNum = new int[newArr.length]; // 奇数位*2的积 <9
        int[] arrSingleNum2 = new int[newArr.length];// 奇数位*2的积 >9
        int[] arrDoubleNum = new int[newArr.length]; // 偶数位数组


        for (int j = 0; j < newArr.length; j++) {
            if ((j + 1) % 2 == 1) {// 奇数位
                if ((newArr[j] - 48) * 2 < 9)
                    arrSingleNum[j] = (newArr[j] - 48) * 2;
                else
                    arrSingleNum2[j] = (newArr[j] - 48) * 2;
            } else
                // 偶数位
                arrDoubleNum[j] = (newArr[j] - 48);
        }


        int[] arrSingleNumChild = new int[newArr.length]; // 奇数位*2 >9
        // 的分割之后的数组个位数
        int[] arrSingleNum2Child = new int[newArr.length];// 奇数位*2 >9
        // 的分割之后的数组十位数


        for (int h = 0; h < arrSingleNum2.length; h++) {
            arrSingleNumChild[h] = (arrSingleNum2[h]) % 10;
            arrSingleNum2Child[h] = (arrSingleNum2[h]) / 10;
        }


        int sumSingleNum = 0; // 奇数位*2 < 9 的数组之和
        int sumDoubleNum = 0; // 偶数位数组之和
        int sumSingleNumChild = 0; // 奇数位*2 >9 的分割之后的数组个位数之和
        int sumSingleNum2Child = 0; // 奇数位*2 >9 的分割之后的数组十位数之和
        int sumTotal = 0;
        for (int m = 0; m < arrSingleNum.length; m++) {
            sumSingleNum = sumSingleNum + arrSingleNum[m];
        }


        for (int n = 0; n < arrDoubleNum.length; n++) {
            sumDoubleNum = sumDoubleNum + arrDoubleNum[n];
        }


        for (int p = 0; p < arrSingleNumChild.length; p++) {
            sumSingleNumChild = sumSingleNumChild + arrSingleNumChild[p];
            sumSingleNum2Child = sumSingleNum2Child + arrSingleNum2Child[p];
        }


        sumTotal = sumSingleNum + sumDoubleNum + sumSingleNumChild
                + sumSingleNum2Child;


        int k = sumTotal % 10 == 0 ? 10 : sumTotal % 10;
        int luhm = 10 - k;


        if (lastNum == luhm) {
            return SUCCESS;// 验证通过
        } else {
            return ILLEGAL_NUMBER;
        }

    }
}
